package org.thanos.iot.service.menu;

import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.thanos.iot.controller.menu.MenuVo;
import org.thanos.iot.entity.menu.SysMenu;
import org.thanos.iot.dao.menu.SysMenuMapper;
import org.thanos.iot.dao.role.SysRoleMenuMapper;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Service("menuService")
public class MenuServiceImpl implements MenuService {

    @Autowired
    private SysMenuMapper menuMapper;

    @Autowired
    private SysRoleMenuMapper iotRoleMenuMapper;

    @Override
    public List<MenuVo> queryAll() {
        List<SysMenu> menus = menuMapper.queryAll();
        if (CollectionUtils.isEmpty(menus)) {
            return Collections.emptyList();
        }
        return this.process(menus, null);
    }

    @Override
    public List<MenuVo> queryByMenuIds(List<Integer> menuIds) {
        List<SysMenu> menus = menuMapper.queryByMenuIds(menuIds);
        if (CollectionUtils.isEmpty(menus)) {
            return Collections.emptyList();
        }
        return this.process(menus, menuIds);
    }

    @Override
    public List<MenuVo> limitMenuList() {
        List<SysMenu> menus = menuMapper.queryAll();
        List<MenuVo> menuVos = menus.parallelStream().map(dataMenu -> {
                    MenuVo menuVo = new MenuVo();
                    menuVo.setId(dataMenu.getId());
                    if (StringUtils.isEmpty(dataMenu.getName())) {
                        menuVo.setName(dataMenu.getOperation());
                    } else {
                        menuVo.setName(dataMenu.getName());
                    }
                    menuVo.setParentId(dataMenu.getParentId());
                    return menuVo;
                }
        ).collect(Collectors.toList());
        return this.recursiveTree(menuVos, 0);
    }

    /**
     * 初始化处理菜单
     *
     * @param menus
     * @return
     */
    private List<MenuVo> process(List<SysMenu> menus, List<Integer> menuIds) {
        List<MenuVo> menuVos = menus.parallelStream().map(dataMenu -> {
                    MenuVo menuVo = new MenuVo();
                    menuVo.setId(dataMenu.getId());
                    menuVo.setName(dataMenu.getName());
                    menuVo.setIcon(dataMenu.getIcon());
                    menuVo.setPath(dataMenu.getPath());
                    menuVo.setLevel(dataMenu.getLevel());
                    if (CollectionUtils.isNotEmpty(menuIds)) {
                        menuVo.setPermits(menuMapper.queryAllPermits(menuIds));
                    }
                    menuVo.setParentId(dataMenu.getParentId());
                    return menuVo;
                }
        ).collect(Collectors.toList());
        return this.recursive(menuVos, 0);
    }

    /**
     * 循环遍历菜单
     *
     * @param menuVos
     * @param parentId
     * @return
     */
    private List<MenuVo> recursive(List<MenuVo> menuVos, Integer parentId) {
        if (CollectionUtils.isEmpty(menuVos)) {
            return Collections.emptyList();
        }
        List<MenuVo> childList = menuVos.parallelStream()
                .filter(menuVo -> menuVo.getParentId().equals(parentId))
                .collect(Collectors.toList());
        // 把子菜单的子菜单再循环一遍,递归
        childList.forEach(menuVo -> menuVo.setChildren(recursive(menuVos, menuVo.getId())));
        // 判断递归结束
        return CollectionUtils.isEmpty(childList) ? null : childList;
    }

    /**
     * 循环遍历菜单
     *
     * @param menuVos
     * @param parentId
     * @return
     */
    private List<MenuVo> recursiveTree(List<MenuVo> menuVos, Integer parentId) {
        if (CollectionUtils.isEmpty(menuVos)) {
            return Collections.emptyList();
        }
        List<MenuVo> childList = menuVos.parallelStream()
                .filter(menuVo -> menuVo.getParentId().equals(parentId))
                .collect(Collectors.toList());
        // 把子菜单的子菜单再循环一遍,递归
        childList.forEach(menuVo -> menuVo.setChildren(recursive(menuVos, menuVo.getId())));
        // 判断递归结束
        return CollectionUtils.isEmpty(childList) ? null : childList;
    }
}
